package ua.pp.fland.multithreading.sorting;

import org.apache.commons.cli.*;
import org.apache.log4j.Logger;

/**
 * @author Maxim Bondarenko
 * @version 1.1 Jul 8, 2010
 */

public class ArgsTokenizer {
    private static final Logger logger = Logger.getLogger(ArgsTokenizer.class);

    private int threadsNum = 0;

    private String fileName;

    private int dataNum;

    private String args[];

    private final Option threadsNumOption;
    private final Option dataNumOption;
    private final Option dataFileOption;

    private CommandLine commandLine;

    private final String usage = "parallelArraySorting -threadsNum [threads num] -dataFile [file name] || " +
            "-dataNum [number of random generated numbers]";

    public ArgsTokenizer(String[] args) {
        this.args = args;

        /*argsNames = new ArrayList<String>(Arrays.asList("threadsNum", "dataNum", "fileName"));
        argsDesc = new ArrayList<String>(Arrays.asList("Number of threads", "Number of random " +
                "generated values", "File name with input data"));*/

        threadsNumOption = new Option("threadsNum", true, "Number of threads");
        threadsNumOption.setType(Number.class);
        dataNumOption = new Option("dataNum", true, "Number of random generated numbers");
        dataNumOption.setType(Number.class);
        dataFileOption = new Option("dataFile", true, "File name with input data");
        dataFileOption.setType(String.class);
    }

    public void parseArgs() throws IllegalArgumentException, ParseException {
        Options options = new Options();
        options.addOption(threadsNumOption);
        options.addOption(dataNumOption);
        options.addOption(dataFileOption);

        Parser parser = new BasicParser();
        commandLine = parser.parse(options, args);

        processInputParams();
    }

    private void processInputParams() throws IllegalArgumentException, ParseException {
        if (!commandLine.hasOption(threadsNumOption.getOpt())) {
            logger.error("Threads nums option not set. " + usage);
            throw new IllegalArgumentException("Threads nums not set.");
        } else {
            threadsNum = new Long((Long) commandLine.getParsedOptionValue(threadsNumOption.getOpt())).intValue();
        }

        if (commandLine.hasOption(dataFileOption.getOpt()) && commandLine.hasOption(dataNumOption.getOpt())) {
            logger.error("Set both dataNum and fileName params. " + usage);
            throw new IllegalArgumentException("Set both dataNum and fileName params.");
        }

        if (!commandLine.hasOption(dataFileOption.getOpt()) && !commandLine.hasOption(dataNumOption.getOpt())) {
            logger.error("Not set dataNum or fileName params. " + usage);
            throw new IllegalArgumentException("Not set dataNum or fileName params.");
        }

        if (commandLine.hasOption(dataNumOption.getOpt())) {
            dataNum = new Long((Long) commandLine.getParsedOptionValue(dataNumOption.getOpt())).intValue();
        }

        if (commandLine.hasOption(dataFileOption.getOpt())) {
            fileName = commandLine.getOptionValue(dataFileOption.getOpt());
        }
    }

    public int getThreadsNum() {
        return threadsNum;
    }

    public Consts getSetDataInput() throws IllegalArgumentException {
        if (commandLine.hasOption(dataNumOption.getOpt())) {
            return Consts.RANDOM_INPUT;
        } else if (commandLine.hasOption(dataFileOption.getOpt())) {
            return Consts.FILE_INPUT;
        } else {
            throw new IllegalArgumentException("Not set dataNum or fileName params.");
        }
    }

    public String getFileName() throws IllegalArgumentException {
        if (!commandLine.hasOption(dataFileOption.getOpt())) {
            logger.error("Input file name not set");
            throw new IllegalArgumentException("Input file name not set");
        }
        return fileName;
    }

    public int getDataNum() throws IllegalArgumentException {
        if (!commandLine.hasOption(dataNumOption.getOpt())) {
            logger.error("Random data num not set");
            throw new IllegalArgumentException("Random data num not set");
        }
        return dataNum;
    }
}
